package contegor.scire.core;

import java.util.Random;


/**
 * IdFragment that will be used to identify transactions. 
 *
 * @version $Revision: 1.1 $
 * @author  Héctor Cirbián Pousa ($Author$)
 */
@Version("$Id$")
public class TransactionId implements IdFragment {
  private static final long serialVersionUID = -4454565019730204171L;

  private static final Random random = new Random(System.currentTimeMillis());

  private String clienName;
  private long number;
  private boolean autocommit;

  protected TransactionId(String clientName, boolean autocommit) {
    this.clienName = clientName;
    this.autocommit = autocommit;
    generateNumber();
  }

  protected void generateNumber() {
    this.number = ((System.currentTimeMillis() << 32) | random.nextInt());
  }

  protected boolean isAutocommit() {
    return autocommit;
  }

  @Override
  public int compareTo(IdFragment obj) {
    if (this == obj)
      return 0;
//    if (!(obj instanceof TransactionId))
//      return this.toString().compareTo(obj.toString());
    TransactionId rhs = (TransactionId)obj;
    int cmp = this.clienName.compareTo(rhs.clienName);
    if (cmp != 0)
      return cmp;
    if (this.number != rhs.number) {
      if (this.number > rhs.number)
        return 1;
      else
        return -1;
    }
    if (this.autocommit != rhs.autocommit)
      return this.autocommit ? 1 :-1;
    assert this.equals(obj);
    return 0; 
  }

//  @Override
//  public int hashCode() {
//    return (int)this.number;
//  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (autocommit ? 1231 : 1237);
    result = prime * result + ((clienName == null) ? 0 : clienName.hashCode());
    result = prime * result + (int) (number ^ (number >>> 32));
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    TransactionId other = (TransactionId) obj;
    if (autocommit != other.autocommit)
      return false;
    if (clienName == null) {
      if (other.clienName != null)
        return false;
    }
    else if (!clienName.equals(other.clienName))
      return false;
    if (number != other.number)
      return false;
    return true;
  }

  @Override
  public String toString() {
    return this.clienName + "." + this.number + " autocommit: " + this.autocommit;
  }
}